package org.f0rb.demo.model.user;

import org.apache.struts2.json.annotations.JSON;
import org.f0rb.demo.utils.SecureUtils;
import org.f0rb.core.web.WebModel;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.UUID;

/** Class org.f0rb.demo.pojo description goes here. */
public final class User extends WebModel<User> {
    public static final String FIELD_USERNAME = "username";
    public static final String FIELD_NICKNAME = "nickname";
    public static final String FIELD_PASSWORD = "password";

    public Integer id;
    public String username;
    public String password;
    public String nickname;
    public String lasthost;
    public Integer online;
    public Boolean active; //是否激活
    public String token; //激活码
    public Timestamp regtime; //注册时间
    public Timestamp lastactive; //上次激活请求
    public Timestamp lastreset; //上次发送密码请求
    public Timestamp lastlogin; //最后登录时间
    public Integer score; //积分

    /** 登录时的验证码. */
    private String verify;
    /** 是否自动登录. */
    private Boolean autologin;
    /** 新密码, 更改密码时同confpass一起使用. */
    private String newpass;
    /** 确认密码, 更改密码时同newpass一起使用. */
    private String confpass;

    public User toSessionUser() {
        User o = new User();
        o.id = id;
        o.username = username;
        o.nickname = nickname;
        o.lastlogin = lastlogin;
        o.active = active;
        return o;
    }

    /**
     * 返回一个初始化好数据的model对象，用于数据库插入
     *
     * @return T 待插入数据库的model对象
     */
    @Override
    public User toInsertModel() {
        User user = clone();
        user.token = UUID.randomUUID().toString().toUpperCase();
        Timestamp now = new Timestamp(System.currentTimeMillis());
        user.regtime = now;
        user.lastactive = now;
        user.active = true;
        user.online = 0;
        user.score = 0;
        user.token = UUID.randomUUID().toString().toUpperCase();
        return user;
    }

    @Override
    public User fillInModel(User user) {
        user.username = username;
        user.nickname = nickname;
        user.password = password;
        user.lasthost = lasthost;
        user.regtime = regtime;
        user.lastactive = lastactive;
        user.active = active;
        user.online = online;
        user.score = score;
        user.token = token;
        return user;
    }

    @Override
    public void fillByModel(User user) {
        if (this == user) return;
        id = user.id;
        username = user.username;
        password = user.password;
        nickname = user.nickname;
        active = user.active;
        lastlogin = user.lastlogin;
        online = user.online;
    }

    @Override
    public String model() {
        return "User";
    }

    @JSON(serialize = false)
    public String getAccount() {
        return new Account(username, String.valueOf(password.hashCode()), lasthost).toString();
    }

    public void setAccount(String s) {
        Account account = new Account(s);
        username = account.username;
        password = account.passcode;
        lasthost = account.host;
    }

    public Integer getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    @JSON(serialize = false)
    public String getPassword() {
        return password;
    }

    public String getNickname() {
        return nickname;
    }

    public String getLasthost() {
        return lasthost;
    }

    public Integer getOnline() {
        return online;
    }

    public Boolean getActive() {
        return active;
    }

    public String getToken() {
        return token;
    }

    public Timestamp getRegtime() {
        return regtime;
    }

    public Timestamp getLastactive() {
        return lastactive;
    }

    public Timestamp getLastreset() {
        return lastreset;
    }

    public Timestamp getLastlogin() {
        return lastlogin;
    }

    public Integer getScore() {
        return score;
    }

    @JSON(serialize = false)
    public String getVerify() {
        return verify;
    }

    public void setVerify(String verify) {
        this.verify = verify;
    }

    @JSON(serialize = false)
    public Boolean getAutologin() {
        return autologin;
    }

    public void setAutologin(Boolean autologin) {
        this.autologin = autologin;
    }

    @JSON(serialize = false)
    public String getNewpass() {
        return newpass;
    }

    public void setNewpass(String newpass) {
        this.newpass = newpass;
    }

    @JSON(serialize = false)
    public String getConfpass() {
        return confpass;
    }

    public void setConfpass(String confpass) {
        this.confpass = confpass;
    }

    class Account {
        /** 自动登录标识的加密密码 IMPORTANT: 建议修改该值后重新编译系统以保证系统的安全性 该密钥的长度必须是8的整数倍 */
        private final static String UUID_ENCRYPT_KEY = "1L2O3G4I5N4D3E2M1O";
        private final static String PATTERN = "{0}#{1}@{2}";
        private final MessageFormat parser = new MessageFormat(PATTERN);

        // 用户名
        private String username;
        // password 的 hashcode
        private String passcode;
        // 用户的主机名
        private String host;
        // username，passcode，host加密后得到的密文
        private String ciphertext;

        /**
         * 用密文初始化
         *
         * @param c 密文
         */
        public Account(String c) {
            ciphertext = c;
            String uuid = SecureUtils.decrypt(ciphertext, UUID_ENCRYPT_KEY);
            try {
                Object[] args;
                args = parser.parse(uuid);
                username = (String) args[0];
                passcode = (String) args[1];
                host = (String) args[2];
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        /**
         * 用属性明文初始化.
         *
         * @param username 用户名
         * @param passcode 密码的hashcode
         * @param host     主机名
         */
        public Account(String username, String passcode, String host) {
            this.username = username;
            this.passcode = passcode;
            this.host = host;
            String uuid = MessageFormat.format(PATTERN, String.valueOf(username), String.valueOf(passcode), host);
            this.ciphertext = SecureUtils.encrypt(uuid, UUID_ENCRYPT_KEY);
        }

        /**
         * 用属性明文初始化.
         *
         * @param userid   用户ID
         * @param passcode 密码的hashcode
         * @param host     主机名
         */
        public Account(int userid, String passcode, String host) {
            this(userid + "", passcode, host);
        }

        public String getUsername() {
            return username;
        }

        public String getPasscode() {
            return passcode;
        }

        public String getHost() {
            return host;
        }

        public String getCiphertext() {
            return ciphertext;
        }

        public String toString() {
            return ciphertext;
        }
    }
}
